package com.qutan.app.core.manager;

import com.alibaba.dubbo.config.annotation.Service;
import com.i7time.entity.SceneInfo;
import com.i7time.entity.User;
import com.i7time.service.SceneService;
import com.i7time.service.UserService;
import com.qutan.app.core.cache.SceneCache;
import com.qutan.app.core.domain.Scene;
import com.qutan.app.core.domain.UserInfo;
import com.qutan.app.core.domain.enumclass.SexType;
import com.qutan.app.core.domain.enumclass.UserStatus;
import com.qutan.app.core.domain.enumclass.Whether;
import com.qutan.app.core.repository.SceneRepository;
import com.qutan.app.core.repository.UserInfoRepository;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by pengweiyuan on 6/12/16.
 */
@Service(version = "1.0.0", interfaceClass = SceneService.class)
public class SceneManager implements SceneService {

    private static Logger logger = org.slf4j.LoggerFactory.getLogger(SceneManager.class);

    private static final int PAGESIZE = 20;//分页默认返回个数

    @Autowired
    private UserInfoRepository userInfoRepository;

    @Autowired
    private SceneRepository sceneRepository;

    @Autowired
    private JedisCluster jedisCluster;

    @Autowired
    private SceneCache sceneCache;

    @Autowired
    private UserManager userManager;

    @Override
    public SceneInfo SceneRegister(long userId, String name, String addr, String mail, String tel, String city, String avatar, String pictures, String latitude, String longtitude, String geohash, String live_channel, String up_url, String down_url) {
        try {
            //Scene(long id,long user_id, String name, String addr, String mail, String tel, String city, String avatar, String pictures, String latitude, String longtitude, String geohash, String live_channel, String up_url, String down_url)
            Scene scene = new Scene(0l, userId, addr, name, mail, tel, city, avatar, pictures, latitude, longtitude, geohash, live_channel, up_url, down_url);
            Scene saveUser = sceneRepository.save(scene);


            userManager.registerSceneUser(tel, name, avatar);
            return saveUser.conver2SceneInfo();
        } catch (Exception e) {
            logger.error("SceneRegister error userId={}", userId, e);
            return null;
        }
    }

    /**
     * 获取场景列表
     *
     * @param city       城市
     * @param latitude   纬度
     * @param longtitude 经度
     * @param page       第几页
     * @return
     */
    @Override
    public List<SceneInfo> getSceneList(String city, double latitude, double longtitude, int page) {
        List<Scene> sceneList = sceneCache.getSceneList(page, PAGESIZE, latitude, longtitude, city.toLowerCase());
        if (sceneList == null || sceneList.isEmpty()) return null;
        List<SceneInfo> result = new ArrayList<>(sceneList.size());
        for (Scene scene : sceneList) {
            result.add(scene.conver2SceneInfo());
        }
        return result;
    }

    @Override
    public SceneInfo getSceneByUserId(long userId) {
        Scene byUserId = sceneRepository.findByuserId(userId);
        if (byUserId != null) {
            Scene scene = getSceneById(byUserId.getId());
            return scene.conver2SceneInfo();
        } else {
            return null;
        }
        // return  null;
    }

    @Override
    public SceneInfo getSceneDetail(long sceneId) {
        Scene sceneById = getSceneById(sceneId);
        if (sceneById != null) return sceneById.conver2SceneInfo();
        else return null;
    }


    /**
     * 根据场景ID获取场景
     *
     * @param sceneId
     * @return
     */
    private Scene getSceneById(long sceneId) {
        try {
            String hgetData = jedisCluster.hget(Scene.getRedisStoreKey(Scene.class), String.valueOf(sceneId));
            if (!StringUtils.isBlank(hgetData)) {
                Scene scene = com.alibaba.fastjson.JSON.parseObject(hgetData, Scene.class);
                return scene;
            } else {
                //查数据库
                Scene scene = sceneRepository.findOne(sceneId);
                if (scene != null) {
                    //加入缓存
                    sceneCache.update(scene);
                    return scene;
                } else {
                    return null;
                }
            }
        } catch (Exception e) {
            logger.error("getSceneDetail error sceneId={} ", sceneId, e);
            return null;
        }
    }

    @Override
    public boolean signIn(long userId, long sceneId) {
        Scene scene = getSceneById(sceneId);
        if (scene == null) {
            logger.warn("signIn warning userId={} sceneId={} scene=null return", userId, sceneId);
            return false;
        }
        UserInfo userInfo = userInfoRepository.findOne(userId);
        if (userInfo == null) {
            logger.warn("signIn warning userId={} sceneId={} userInfo=null return", userId, sceneId);
            return false;
        }
        if (scene.getRoomMembers() == null)
            scene.setRoomMembers(new ArrayList<>());
        if(!scene.getRoomMembers().contains(userInfo)){
            scene.getRoomMembers().add(userInfo);
            sceneCache.update(scene);
        }
        System.err.println("userId="+userId+" 迁入成功>......");
        return true;
    }

    @Override
    public long getDistance(long sceneId, double userlongtitude, double userlatitude) {
        return 0;
    }

    @Override
    public boolean signOut(long userId, long sceneId) {
        Scene scene = getSceneById(sceneId);
        if (scene == null) {
            logger.warn("signIn warning userId={} sceneId={} scene=null return", userId, sceneId);
            return false;
        }
        UserInfo userInfo = userInfoRepository.findOne(userId);
        if (userInfo == null) {
            logger.warn("signIn warning userId={} sceneId={} userInfo=null return", userId, sceneId);
            return false;
        }
        System.err.println("+++++online pengole="+scene.getRoomMembers().size());
        scene.getRoomMembers().remove(userInfo);
        sceneCache.update(scene);
        System.err.println("+++++online pengole="+scene.getRoomMembers().size());
        return true;
    }

    @Override
    public int getLiveStatus(long sceneId) {
        Scene scene = getSceneById(sceneId);
        if (scene == null) {
            logger.warn("getLiveStatus  sceneId={} scene=null return", sceneId);
            return Whether.NO.getSort();
        }
        return scene.getIsOnline() == null ? Whether.NO.getSort() : scene.getIsOnline().getSort();
    }

    @Override
    public long getOnlivePeoples(long sceneId) {
        Scene scene = getSceneById(sceneId);
        if (scene == null) {
            logger.warn("getLiveStatus  sceneId={} scene=null return", sceneId);
            return 0;
        }
        return scene.getRoomMembers() == null ? 0 : scene.getRoomMembers().size();
    }


    /**
     * 获得在场景里面在线的人数
     *
     * @param sceneId
     * @return
     */
    @Override
    public long getOnLinePeoples(long sceneId) {
        List<User> users = getRoomMembers(sceneId);
        return users == null ? 0 : users.size();
    }


    @Override
    public List<User> getRoomMembers(long sceneId) {
        Scene scene = getSceneById(sceneId);
        if (scene == null) {
            logger.warn("getRoomMembers  sceneId={} scene=null return", sceneId);
            return null;
        }
        if (scene.getRoomMembers() == null) return null;
        List<UserInfo> roomMembers = scene.getRoomMembers();
        if (roomMembers == null || roomMembers.isEmpty()) return null;
        List<User> result = new ArrayList<>(roomMembers.size());
        roomMembers.forEach(u -> {
            result.add(u.converInfo2User());
        });
        return result;
    }

    @Override
    public List<User> getRoomLiveMembers(long sceneId) {
        Scene scene = getSceneById(sceneId);
        if (scene == null) {
            logger.warn("getRoomMembers  sceneId={} scene=null return", sceneId);
            return new ArrayList<User>();
        }
        return getRoomerberByCondition(scene, UserStatus.ONLIVE);
    }


    @Override
    public boolean isUserInScene(long userId, long sceneId) {
        Scene scene = getSceneById(sceneId);
        if (scene == null) {
            logger.warn("isUserInScene  sceneId={} scene=null return", sceneId);
            return false;
        }
        if (scene.getRoomMembers() == null) return false;
        List<UserInfo> roomMembers = scene.getRoomMembers();
        long count = roomMembers.stream().filter(user -> user.getId()== userId).count();
        return count > 0;
    }


    /**
     * 根据条件获取场景的人
     *
     * @param scene
     * @param status
     * @return
     */
    private List<User> getRoomerberByCondition(Scene scene, UserStatus status) {
        if (scene.getRoomMembers() == null) return null;
        List<UserInfo> roomMembers = scene.getRoomMembers();
        if (roomMembers == null || roomMembers.isEmpty()) return new ArrayList<User>();
        List<User> result = new ArrayList<>(roomMembers.size());
        roomMembers.forEach(u -> {
            if (u.getUserStatus() == status)
                result.add(u.converInfo2User());
        });
        return result;
    }
}
